/*
 * Copyright 2010 Thedwick, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package com.thedwick.jdbcGrabber.analysis;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.thedwick.jdbcGrabber.analysis.parser.CapturedColumn;
import com.thedwick.jdbcGrabber.analysis.parser.CapturedStatement;
import com.thedwick.jdbcGrabber.analysis.parser.CapturedTable;
import com.thedwick.jdbcGrabber.analysis.parser.CapturedTrace;
import com.thedwick.jdbcGrabber.analysis.parser.CapturedTraceElement;
import com.thedwick.jdbcGrabber.analysis.parser.FileBasedResultsParser;
import com.thedwick.jdbcGrabber.analysis.parser.ResultsParser;

/**
 * Takes one or more sets of captured data and summarizes them in a human readable format to standard out.
 * 
 * @author trcull
 *
 */
public class BasicSummary {
	private static final int TABLE = 1;
	private static final int COLUMNS = 2;
	private static final int FULL = 0;

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		if (args.length < 2){
			System.err.println("Usage: BasicSummary <filepath> <packageprefix> <'table'|'columns'|'full'> <sinkname1> <sinkname2> ...." +
					"\nWhere" +
					"\n<filepath> is the path to all the captured data files produced by a SummarizingSink and a FileSummaryStore, for example '/tmp'" +
					"\n<packageprefix> is the prefix of the Java packages that belong to your organization, for example 'com.yahoo.'" +
					"\n<'table'|'columns'|'full'> to specify the level of granularity to give for sql statements" +
					"\n<sinkname> is one or more names, as specified by the 'sink.name' property in your connection's properties file");
			System.exit(1);
		}
		String path = args[0];
		String packageName = args[1];
		String granularityStr = args[2];
		int granularity = FULL; //default to full
		if (granularityStr.equals("table")){
			granularity = TABLE;
		} else if (granularityStr.equals("columns")){
			granularity = COLUMNS;
		} 
		List<String> sinks = new ArrayList<String>(args.length - 3);
		for (int i=3 ; i < args.length; i++){
			sinks.add(args[i]);
		}
		BasicSummary summary = new BasicSummary();
		summary.summarize(path, packageName, granularity, sinks);
		
		
	}

	private void summarize(String path, String packageName, int granularity, List<String> sinks) throws IOException {
		for (String sink : sinks){
			out("\n\n+++++++++++++++++++++++++++++++\n\nFor sink: " + sink);
			ResultsParser parser = new FileBasedResultsParser(sink,path);
			Set<CapturedStatement> statements = parser.parse();
			for (CapturedStatement statement : statements){
				out("\n=====================================\n");
				StringBuilder builder = new StringBuilder();
				switch (granularity){
				case TABLE:
					for (CapturedTable table : statement.getTables()){
						builder.append(table.getName());
						builder.append(",");
					}
					out(builder.toString());
					break;
				case COLUMNS:
					for (CapturedColumn column : statement.getColumns()){
						builder.append(column.getName());
						builder.append(",");
					}
					out(builder.toString());
					break;
				case FULL:
				default:
					out(statement.getSql());
					break;
				}
				out("\n...is called " + statement.getCount() + " times from...\n");
				for (CapturedTrace trace : statement.getTraces()){
					out(trace.getCount() + " times");
					List<CapturedTraceElement> elements = trace.getElements();
					int size = elements.size();
					for (int i=0 ; i<size ; i++){
						CapturedTraceElement element = elements.get(i);
						//output only the first and last elements plus any that belong to this organization
						if (i == 0 || i == (size-1) || element.getClassName().startsWith(packageName)){
							out("\t"+ element.getClassName() + "." + element.getMethodName() + "(" + element.getLineNumber() + ")");
						}
					}
				}
			}
		}
	}

	private void out(String string) {
		System.out.println(string);
	}


}
